package com.ronan.imweb.service.impl;

import com.ronan.common.constant.Constants;
import com.ronan.common.pojo.SendMsgReq;
import com.ronan.common.pojo.SendMsgVo;
import com.ronan.common.response.Result;
import com.ronan.common.utils.RouteManager;
import com.ronan.imweb.rpc.IMServerRpcService;
import com.ronan.imweb.service.MessageService;
import com.ronan.imweb.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * FileName    : com.ronan.imweb.service.impl
 * Description :
 *
 * @author : ronan
 * @version : 1.0
 * Create Date : 2021/2/27 17:39
 **/
@Slf4j
@Service
public class MessageServiceImpl implements MessageService {


    @Autowired
    private IMServerRpcService rpcService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RedisService redisService;

    /**
     * v1发送消息
     * 用户建立tcp连接时,将自身消息推送的接口保存到了redis
     * 这里根据id去取得所要调用的服务接口
     *
     * @param req 请求参数
     * @return {@link Result < SendMsgVo >}
     */
    @Override
    public Result<SendMsgVo> v1SendMessage(SendMsgReq req) {
        // 先判断客户端B是否在线
        Boolean isMember = redisService.sIsMember(Constants.LOGIN_STATUS_PREFIX, req.getTo());
        if (!isMember) {
            log.info("用户:{},不在线",req.getTo());

        }



        // 根据消息推送对象id找到消息推送对象所建立长连接的服务器,拿到rpc路由
        String route = doRoute(req.getTo());
        log.info("发送者:[{}],接收者[{}],路由:{}", req.getFrom(), req.getTo(), route);

        // 创建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<SendMsgReq> request = new HttpEntity<>(req, headers);
        return restTemplate.postForObject("http://" + route + "/rpc/rim/v1SendMsg", request, Result.class);
        // return rpcService.v1SendMsg(req);
    }


    /**
     * 获取路由,并保存本地内存
     *
     * @param id id
     * @return {@link String}
     */
    public String doRoute(String id) {
        String route = RouteManager.getRoute(id);
        if (null == route) {
            synchronized (this) {
                route = RouteManager.getRoute(id);
                if (null == route) {
                    route = (String) redisService.get(Constants.ROUTE_PREFIX + id);
                    log.info("从redis缓存中获取route:{}", route);
                    if (null != route) {
                        RouteManager.putRoute(id, route);
                    }
                } else {
                    log.info("从本地缓存中获取route:{}", route);
                }
            }
        } else {
            log.info("从本地缓存中获取route:{}", route);
        }
        return route;
    }
}
